﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DataCenter.Models;
using System.Reflection;

namespace Client.Panels
{
    public abstract class ILinePanel<T>:BasePanel
    {
        protected override string[] parentsName => new string[] { "ILinePanel", "BasePanel" };

        protected DataCenter.Models.IInfo ggInfo;
        protected T[] data;
        protected List<YYBeep.Beep[]> lines = new List<YYBeep.Beep[]>();
        Enums.feedbackType fType = Enums.feedbackType.SOUND;
        protected bool[] selectedLine;
        protected int startPoint = 0;
        protected int endPoint = 0;

        protected int beepTime = Managers.Manager.beepM.generalWav;
        protected int beepEmptyTime = Managers.Manager.beepM.generalWavEmpty;

        protected ILinePanel(IInfo ggInfo, string clientText):base(clientText)
        {
            this.ggInfo = ggInfo;
            RegisterHotkey("ILinePanel");
            isTemp = true;
            horizontal = false;
            speakIndexColumn = false;
        }

        public override void OnAwake()
        {
            //XBorder += Managers.Manager.beepM.PlayXBorder;
            //YBorder += Managers.Manager.beepM.PlayYBorder;
            //NoItem += Managers.Manager.beepM.PlayNoItem;
            base.OnAwake();
            Init();
        }

        async void Init()
        {
            var res = await InitLines();
            if (res == -1)
            {
                System.Windows.Forms.MessageBox.Show("没有数据", "提示");
                StockMenuFuncs.ChoiceKTime(ggInfo);
                return;
            }

            FillFields<T>(panelName);
            UpdatePanel<T>(data);

            InitSelectedLine();

            Managers.Manager.beepM.PlaySuccessed();
        }


        public override void Up()
        {
            y--;
            Navigation(true);
        }
        public override void Down()
        {
            y++;
            Navigation(true);
        }
        public override void Left()
        {
            x--;
            Navigation(false);
        }
        public override void Right()
        {
            x++;
            Navigation(false);
        }
        public override void FirstItem()
        {
            x = 0;
            Navigation(false);
        }
        public override void LastItem()
        {
            x = items.Count - 1;
            Navigation(false);
        }
        public void SpeakHeader()
        {
            isSpeakHeader = !isSpeakHeader;
            if (isSpeakHeader)
                Managers.Manager.ttsM.Speak("朗读名称");
            else
                Managers.Manager.ttsM.Speak("不朗读名称");
        }
        public void SetStartPoint()
        {
            if (x > -1)
            {
                startPoint = x;
                Managers.Manager.ttsM.Speak("选择开始点");
            }
        }
        public abstract void SetEndPoint();
        public void JumpToStartPoint()
        {
            x = startPoint;
            Managers.Manager.beepM.PlayBeep(lines[y][x]);
            Managers.Manager.ttsM.Speak("跳转到开始点");
        }
        public void JumpToEndPoint()
        {
            x = endPoint;
            Managers.Manager.beepM.PlayBeep(lines[y][x]);
            Managers.Manager.ttsM.Speak("跳转到结束点");
        }
        protected int GetHighestAndLowest<TFiled>(int startP, int endP, PropertyInfo property, bool biggest = true, int offset = 0) where TFiled : IComparable
        {
            if (startP > endP)
            {
                int x = startP;
                startP = endP;
                endP = x;
            }

            TFiled tmp = (TFiled)property.GetGetMethod().Invoke(data[startP], null);
            int res = startP;
            for (int i = offset + startP; i <= endP; i++)
            {
                TFiled tmp2 = (TFiled)property.GetGetMethod().Invoke(data[i], null);
                if (biggest && tmp.CompareTo(tmp2) < 0)
                {
                    tmp = tmp2;
                    res = i;
                    continue;
                }
                if (!biggest && tmp.CompareTo(tmp2) > 0)
                {
                    tmp = tmp2;
                    res = i;
                    continue;
                }
            }

            return res;
        }


        public void ChangeFeedbackType()
        {
            switch (fType)
            {
                case Enums.feedbackType.SOUND:
                    fType = Enums.feedbackType.VOICE;
                    Managers.Manager.ttsM.Speak("语音");
                    break;
                case Enums.feedbackType.VOICE:
                    fType = Enums.feedbackType.BOTH;
                    Managers.Manager.ttsM.Speak("两者");
                    break;
                case Enums.feedbackType.BOTH:
                    fType = Enums.feedbackType.SOUND;
                    Managers.Manager.ttsM.Speak("音效");
                    break;
            }
        }

        public void SelectLine()
        {
            if (y < selectedLine.Length)
            {
                selectedLine[y] = !selectedLine[y];
                if (selectedLine[y])
                    Managers.Manager.ttsM.Speak("已选中");
                else
                    Managers.Manager.ttsM.Speak("未选中");
            }
        }

        protected void Navigation(bool upAndDown)
        {
            if (x == -1)
                return;

            switch (fType)
            {
                case Enums.feedbackType.SOUND:
                    SoundFeedback(upAndDown);
                    break;
                case Enums.feedbackType.VOICE:
                    SpeakCell(upAndDown);
                    break;
                default:
                    svFeedback(upAndDown);
                    break;
            }

        }
        protected virtual void SoundFeedback(bool upAndDown)
        {
            if (y < lines.Count)
            {
                if (upAndDown)
                {
                    string str = "";
                    if (isSpeakHeader)
                        str += panelHeader[y];
                    if (selectedLine[y] && isSpeakHeader)
                        str += "已选中";
                    lines[y][x].time = beepTime;
                    Managers.Manager.beepM.PlayBeep(lines[y][x]);
                    Managers.Manager.ttsM.Speak(str);

                    lines[y][x].time = Managers.Manager.beepM.generalWav;
                }
                else
                {
                    LeftAndRight();
                }
            }
            else
                SpeakCell(upAndDown);
        }
        protected virtual void svFeedback(bool upAndDown)
        {
            if (y < lines.Count)
            {
                lines[y][x].time = beepTime;
                Managers.Manager.beepM.PlayBeep(lines[y][x]);
                lines[y][x].time = Managers.Manager.beepM.generalWav;
            }
            SpeakCell(upAndDown);
        }

        void LeftAndRight()
        {
            if (x == -1)
                return;

            List<YYBeep.Beep> beeps = new List<YYBeep.Beep>();
            for (int i = 0; i < selectedLine.Length; i++)
            {
                if (selectedLine[i] == true)
                {
                    var b = lines[i][x];
                    b.time = beepTime;
                    beeps.Add(b);
                    beeps.Add(YYBeep.Beep.CreateEmptyBeep(beepEmptyTime));
                }
            }
            Managers.Manager.beepM.PlayBeeps(beeps.ToArray());

            for(int i = 0; i < beeps.Count; i += 2)
            {
                beeps[i].time = Managers.Manager.beepM.generalWav;
            }
        }


        protected void PlayLine(int startPoint, int endPoint)//包含开始点和结束点
        {
            if (y < lines.Count)
            {
                int span = 1;
                if (Math.Abs(endPoint - startPoint) > 200)
                    span = 4;
                else if (Math.Abs(endPoint - startPoint) > 100)
                    span = 2;

                List<YYBeep.Beep> bs = new List<YYBeep.Beep>();
                int fuhao;  //获取开始点减去结束点的符号
                if (startPoint == endPoint)
                    fuhao = 1;
                else
                    fuhao = (endPoint - startPoint) / Math.Abs(endPoint - startPoint);
                for (int i = 0; i <= Math.Abs(startPoint - endPoint); i += span)
                {
                    var index = startPoint + i * fuhao;
                    if (index < 0)
                        index = 0;
                    else if (index >= lines[y].Length)
                        index = lines[y].Length - 1;
                    bs.Add(lines[y][index]);
                }

                Managers.Manager.beepM.PlayBeeps(bs.ToArray());
            }
        }
        protected void SpeakTime()
        {
            string str = this[items[x].Count - 1, x].text;
            Managers.Manager.ttsM.Speak(str);
        }

        void InitSelectedLine()
        {
            selectedLine = new bool[lines.Count];
            var l = new string[] { "trade", "average" };
            for (int i = 0; i < panelHeader.Count; i++)
            {
                foreach (var j in l)
                {
                    if (panelHeader[i] == Managers.Manager.jargonM.GetJargon(j))
                    {
                        selectedLine[i] = true;
                        break;
                    }
                }

            }
        }


        protected abstract Task<int> InitLines();

        public override void OnSleep()
        {
            base.OnSleep();
            Managers.Manager.beepM.PlayBack();
        }
        protected override void UpdateHotStockInfo() { }
        protected override void ClearCron() { }
    }
}
